/**
 * create by young (young2f@outlook.com) on 2023/6/17
 * mqtt收到设备消息后，通过eventBus发布
 * 同一台设备可能有多个订阅，所以某个退出后不能取消订阅，todo 待优化 removeSubscribe
 */
'use strict';
const _ = require('lodash');
const emq = require('mqtt');
const StringDecoder = require('string_decoder').StringDecoder;
const moment = require("moment");
module.exports = class {
    constructor(app) {
        this.app = app;
        this.config = app.config;
        this.client = undefined;
        this.topics = [];
        this.publishCache = [];
    }

    init() {
        if (this.client !== undefined) {
            this.client.end();
            this.client = undefined;
        }
        const {url, port} = this.app.iiotConfig.mqtt;

        this.app.logger.info('正在连接DEVICE MQTT', url, port);
        const qos = 0;
        const opts = {port, qos};
        this.client = emq.connect(url, opts);
        this.client.on('connect', packet => {
            this.app.logger.info('IIOT平台连接成功!!!', url, port);

            var topics = [
                '+/databack',
                '+/ctrlReport'
            ];
            _.map(topics, topic => {
                const qos = 0
                this.client.subscribe(topic, { qos }, (error) => {
                    if (error) {
                        console.log('subscribe error:', error)
                        return
                    }
                    console.log(`Subscribe to topic '${topic}'`)
                })

            })
            /**
             * mqtt订阅消息到达
             */

            this.client.on('message', async (topic, message) => {
                console.log(topic, message);
                const payload = buffer2json(message);
                this.app.logger.info(topic, payload);
                if (!payload) return;

              //  const res = await this.app.deviceMgr.onData({topic, payload})

            });
            this.client.on('error', error => {
                this.app.logger.error('IIOT平台连接 error', url);
                this.app.eventBus.emit('MQTT_CONNECTED', 'error');
            });
            this.client.on('close', error => {
                this.app.logger.error('IIOT平台连接 close', url);
                this.app.eventBus.emit('MQTT_CONNECTED', 'close');
            });

            this.client.on('offline', error => {
                this.app.logger.error('IIOT平台连接 offline', url);
                this.app.eventBus.emit('MQTT_CONNECTED', 'offline');
            });
            return Promise.resolve('');
        })
    };
}

function buffer2json(buffer) {
    try {
        const decoder = new StringDecoder('utf8');
        let str = decoder.write(buffer);
        return str2json(str);
    } catch (e) {
        console.error(e);
        return undefined;
    }
}

function str2json(str, isDebug) {
    try {
        if (typeof str === 'object') {
            return str;
        }
        if (typeof str === 'array') {
            return str;
        }
        if (str === undefined || str === null || str === '') {
            console.error('str2json error:str is null');
            return;
        }
        if (typeof str === 'string') {
            return JSON.parse(str);
        }
        const key = '{\\';
        if (str.startsWith(key)) {
            str = str.replace(/[\\]/g, '');
        }
        let json = JSON.parse(str);

        if (typeof json === 'string') {
            json = eval('(' + json + ')');
            return str2json(json);
        }
        return json;
    } catch (e) {
        console.error('str2json error', str);
        return undefined;
    }
}
